
//录音程序,演示alsa library的使用
#include<stdio.h>
#include <alsa/asoundlib.h>
#include <signal.h>
//是否停止录音
int interrupted=0;

//处理ctrl+C信号
void  handle_sigint(int signo)
{
	interrupted=1;
}
int main(void)
{
	signal(SIGINT,handle_sigint);
	//打开设备
	//参数1： 声卡设备的句柄  snd_pcm_t *
	//
	//参数2：设备的名字 ,使用默认的声音设备-->sysdefault
	
	//参数3:SND_PCM_STREAM_CAPTURE 录音
	//      SND_PCM_STREAM_PLAYBACK 放音
	//      参数1:同步 0
	//      异步:1/2
	//     返回:0成功,否则失败,错误码
	snd_pcm_t * mic=NULL;
	
	//1.打开默认的音频设备
	int error=snd_pcm_open(&mic,"sysdefault",SND_PCM_STREAM_CAPTURE,0);

	if(error!=0)
	{
		perror("snd_pcm_open failed");
		return -1;
	}

	//2.设置硬件参数
	snd_pcm_hw_params_t * hw_params;

	//分配硬件参数内存
	snd_pcm_hw_params_alloca(&hw_params);

	//初始化硬件参数,使用默认值
	snd_pcm_hw_params_any(mic,hw_params);

	//多声道交错存储,读写方式
	snd_pcm_hw_params_set_access(mic,hw_params,SND_PCM_ACCESS_RW_INTERLEAVED);

	//设置采样格式,有符号16位整数,小端字节序
	
	snd_pcm_hw_params_set_format(mic,hw_params,SND_PCM_FORMAT_S16_LE);

	//设置采样率:16000HZ
	snd_pcm_hw_params_set_rate(mic,hw_params,16000,0);

	//设置声道数:单声道
	
	snd_pcm_hw_params_set_channels(mic,hw_params,1);

	

	//根据硬件参数设置声卡设备
	error=snd_pcm_hw_params(mic,hw_params);

	if(error!=0)
	{
		perror("snd_pcm_open failed\n");
		return -1;
	}
	


	//创建文件
	FILE * fp=fopen("test.pcm","w");

	if(fp==NULL)
	{
		perror("fopen failed");
		return -1;
	}


	
	

	unsigned long period=0;
	int dir=0;
	//获取声卡一次性获取数据的大小
	snd_pcm_hw_params_get_period_size(hw_params,&period,&dir);

	printf("period:%ld\n",period);
	//char buf[]
	//开始读取
	

	//bufd大小必须是period的整数倍
	char buf[682]={'\0'};


	//开始录音
	snd_pcm_prepare(mic);

	while(interrupted!=1){
		//从声卡读数据写入到音频文件
		snd_pcm_sframes_t  frames=snd_pcm_readi(mic,buf,period);
		//写入到文件中去,将侦数转成字节数
		fwrite(buf,1,snd_pcm_frames_to_bytes(mic,frames),fp);
	}


	//关闭文件
	
	//停止录音
	snd_pcm_drain(mic);//等待声卡缓冲区的数据读取完成
	snd_pcm_close(mic);
	fclose(fp);
	

	return 0;
}
